﻿using System;
using System.ComponentModel;

namespace goAlarmsCS
//todo: remove dependency on IAlarmScheduler...instead IAlarmScheduler will depend on Alarm
{
    public abstract class Alarm : INotifyPropertyChanged, IAlarm  //, Alarm
    {
        #region Fields and Properties
        protected string _name;
        public string Name
        {
            get { return _name; }
            set
            {
                if (_name == value)
                    return;

                _name = value;
                OnPropertyChanged("Name");
            }
        }

        protected string _group;
        public string Group
        {
            get { return _group; }
            set
            {
                if (_group == value)
                    return;

                _group = value;
                OnPropertyChanged("Group");
            }
        }

        protected string _popupText;
        public string PopupText
        {
            get { return _popupText; }
            set
            {
                if (_popupText == value)
                    return;

                _popupText = value;
                OnPropertyChanged("PopupText");
            }
        }      //text that displays when alarm is triggered
        protected bool _enabled;
        public bool Enabled
        {
            get { return _enabled; }
            set
            {
                if (_enabled == value)
                    return;

                _enabled = value;
                OnPropertyChanged("Enabled");
            }
        }          //disabled alarms (enabled=false) are never triggered
        protected bool _silenced;
        public bool Silenced
        {
            get { return _silenced; }
            set
            {
                if (_silenced == value)
                    return;

                _silenced = value;
                OnPropertyChanged("Silenced");
            }
        }         //display but suppress noise.
        protected bool _active;
        public bool Active  //an active alarm is one that has been triggered but it might be snoozed. 
        {
            get { return _active; }
            set
            {
                if (_active == value)
                    return;

                _active = value;
                OnPropertyChanged("Active");
            }
        }           
        protected bool _snoozed;
        public bool Snoozed       //alarms has been snoozed
        {
            get { return _snoozed; }
            set
            {
                if (_snoozed == value)
                    return;

                _snoozed = value;
                OnPropertyChanged("Snoozed");
            }
        }   
        protected int _frequency;
        public int Frequency   //for recurring alarms time in minutes between triggers.
        {
            get { return _frequency; }
            set
            {
                if (_frequency == value)
                    return;

                _frequency = value;
                OnPropertyChanged("Frequency");
            }
        }      

        protected int _snoozeDuration;
        public int SnoozeDuration
        {
            get { return _snoozeDuration; }
            set
            {
                if (_snoozeDuration==value)
                    return;

                _snoozeDuration = value;
                OnPropertyChanged("SnoozeDuration");
            }
        }

        private int _autoSnoozeDuration;
        public int AutoSnoozeDuration   //0 duration means no auto-snooze
        {
            get { return _autoSnoozeDuration; }
            set
            {
                _autoSnoozeDuration = value;
                OnPropertyChanged("AutoSnoozeDuration");
            }
        }

        private byte _autoSnoozeMaxCount;
        public byte AutoSnoozeMaxCount   //max number of time to allow auto-snooze
        {
            get { return _autoSnoozeMaxCount; }
            set
            {
                _autoSnoozeMaxCount = value;
                OnPropertyChanged("AutoSnoozeMaxCount");
            }
        }

        private byte _snoozedCurrentCount;
        public byte SnoozedCurrentCount   //numbe of times this alarm has been snoozed.
        {
            get { return _snoozedCurrentCount; }
            set
            {
                _snoozedCurrentCount = value;
                OnPropertyChanged("SnoozedCurrentCount");
            }
        }

        public DateTime NextTriggerTime { get; set; }

        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged(string name)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(name));
            }
        }
        public Func<CreateTriggerArgs, Object> CreateTriggerFunction { get; set; }

        #endregion

        #region Constructors

        //AlarmScheduler _alarmScheduler;
        protected Alarm()
        {
        }

        //private Alarm() { } //use public constructor only.

        #endregion

        #region Events, delegates and abstract members
        
        public event EventHandler Trigger;
        protected void OnTrigger(EventArgs e)
        {
            var temp = Trigger;
            if (temp != null)
                temp(this, e);
        }

        public void  TriggerHandler()
        {
            OnTrigger(new AlarmEventArgs(this));
        }

        public abstract void DoSnooze();

        public abstract void DoReset();

        protected abstract void SetNextTriggerTime();

        protected abstract AlarmTypes alarmType { get; }

        #endregion

    }
}